package com.liveneo.adapter.base.support;

import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.liveneo.adapter.base.service.ConfigurationService;

@Component
public class OssManagerTool {
    @Autowired
    private ConfigurationService configurationService;

    /**
     * 上传文件
     * 
     * @param content 文件输入流
     * @param key 上传为OSS文件服务器的唯一标识
     * @param mimeType 文件类型
     * @return
     * @throws Exception
     */
    public String uploadFile(InputStream content, String key, String mimeType) throws Exception {
        LogUtils.info("[oss]上传文件开始【key: " + key + ", mimeType: " + mimeType + "】");
        OSSClient client = null;
        ObjectMetadata meta = null;
        String result = "";
        try {
            client = buildOssClient();
            meta = buildObjectMetadata(mimeType);
            LogUtils.info("[oss]上传文件【 client state:" + client + "】");
            // 上传文件
            PutObjectResult putObjectResult = client.putObject(configurationService.getBucketName(), key, content, meta);
            result = putObjectResult.getETag();
            LogUtils.info("[oss]上传文件结束【key: " + key + "】，返回结果【result: " + result + "】");
        } catch (Exception e) {
            LogUtils.error("[oss]上传文件失败【key: " + key + "】，异常【" + e.getMessage() + "】", e);
            throw new Exception(e);
        } finally {
            // 关闭OSS客户端
            destoryOssClient(client);
        }
        return result;
    }

    /**
     * 根据key获取oss服务器上的图片公网地址
     * 
     * @param key
     * @return
     */
    public String getImgURl(String key) {
        LogUtils.info("[oss]获取图片URL开始【key: " + key + "】");
        if (StringUtils.isBlank(key)) {
            return "";
        }
        OSSClient client = null;
        URL url = null;
        try {
            client = this.buildOssClient();
            // URL超时时间（30分钟）
            Date expires = DateUtils.addMilliseconds(new Date(), Integer.parseInt(configurationService.getOutOfDate()));
            // 创建生成带有签名信息的URL的请求的实例对象
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(configurationService.getBucketNameByKey(key), key);
            // 设置URL超时时间
            generatePresignedUrlRequest.setExpiration(expires);
            url = client.generatePresignedUrl(generatePresignedUrlRequest);
            LogUtils.info("[oss]获取图片URL结束【key: " + key + "】，返回结果【" + url.toString() + "】");
        } catch (Exception e) {
            LogUtils.error("[oss]获取图片URL失败【key: " + key + "】，异常【" + e.getMessage() + "】", e);
            throw new RuntimeException(e);
        } finally {
            // 关闭OSS客户端
            this.destoryOssClient(client);
        }
        return url != null ? url.toString() : "";
    }

    /**
     * 根据key获取oss服务器上的ipa文件公网地址
     * 
     * @param key
     * @return
     */
    public String getIpaURl(String key) {
        LogUtils.info("[oss]获取ipa文件URL开始【key: " + key + "】");
        if (StringUtils.isBlank(key)) {
            return "";
        }
        OSSClient client = null;
        URL url = null;
        try {
            client = this.buildOssClient();
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(configurationService.getBucketNameByKey(key), key);
            // 设置有效期为10年，原默认值
            generatePresignedUrlRequest.setExpiration(DateUtils.addYears(new Date(), 10));
            url = client.generatePresignedUrl(generatePresignedUrlRequest);
            LogUtils.info("[oss]获取ipa文件URL结束【key: " + key + "】，返回结果【" + url.toString() + "】");
        } catch (Exception e) {
            LogUtils.error("[oss]获取ipa文件URL失败【key: " + key + "】，异常【" + e.getMessage() + "】", e);
            throw new RuntimeException(e);
        } finally {
            // 关闭OSS客户端
            this.destoryOssClient(client);
        }
        return url != null ? url.toString() : "";
    }

    /**
     * 根据key获取oss服务器上的文件输入流
     * 
     * @param key
     * @return
     */
    public InputStream getObject(String key) {
        LogUtils.info("[oss]获取文件输入流开始【key: " + key + "】");
        if (StringUtils.isBlank(key)) {
            return null;
        }
        OSSObject object = null;
        OSSClient client = null;
        InputStream objectContent = null;
        try {
            client = this.buildOssClient();
            object = client.getObject(configurationService.getBucketNameByKey(key), key);
            String contentType = object.getObjectMetadata().getContentType();
            // 获取Object的输入流
            objectContent = object.getObjectContent();
            LogUtils.info("[oss]获取文件输入流结束【key: " + key + "】，文件类型【" + contentType + "】");
        } catch (Exception e) {
            LogUtils.error("[oss]获取文件输入流失败【key: " + key + "】，异常【" + e.getMessage() + "】", e);
            throw new RuntimeException(e);
        } finally {
            // 关闭OSS客户端
            this.destoryOssClient(client);
        }
        return objectContent;
    }

    /**
     * 删除文件
     * 
     * @param key OSS文件服务器上文件的唯一标识
     */
    public void deleteFile(String key) {
        LogUtils.info("[oss]删除文件开始【key: " + key + "】");
        OSSClient client = null;
        try {
            client = this.buildOssClient();
            // 删除对象
            client.deleteObject(configurationService.getBucketName(), key);
            LogUtils.info("[oss]删除文件结束【key: " + key + "】");
        } catch (Exception e) {
            LogUtils.error("[oss]删除文件结束【key: " + key + "】，异常【" + e.getMessage() + "】", e);
            throw new RuntimeException(e);
        } finally {
            // 关闭OSS客户端
            this.destoryOssClient(client);
        }
    }

    /**
     * 创建一个OSSClient
     * 
     * @return
     */
    private OSSClient buildOssClient() {
        return new OSSClient(configurationService.getEndpointInternal(), configurationService.getAccessKeyId(), configurationService.getAccessKeySecret());
    }

    /**
     * 创建元数据对象
     * 
     * @param mimeType 文件类型
     * @return
     */
    private ObjectMetadata buildObjectMetadata(String mimeType) {
        ObjectMetadata meta = new ObjectMetadata();
        meta.setContentType(mimeType);
        return meta;
    }

    /**
     * 关闭oss客户端
     * 
     * @param client
     */
    public void destoryOssClient(OSSClient client) {
        // 关闭oss客户端
        if (client != null) {
            client.shutdown();
        }
    }
}
